import { message } from 'antd';
import router from 'umi/router';
import memoizeOne from 'memoize-one';
import isEqual from 'lodash/isEqual';
import sortBy from 'lodash/sortBy';
import findIndex from 'lodash/findIndex';
import find from 'lodash/find';
import mapping, {
  getAllMenu,
  getRecentMenuInfo,
  // getSysCodeBySysNbr,
  selectMenuByLetter,
  // updateRecentMenu,
  getCollectionMenu,
  updateCollectionMenu,
  fetchMenu,
} from '@/services/menu';
import { checkMenuPar, transform } from '@/layouts/BasicLayout/components/utils';
import { visitor } from '@/defaultSettings';
import allMenu from '@/menu';

const {
  MENU_TYPE_LEAF,
  MENU_OPEN_MODE_WORK_BENCH_LABEL,
  // eslint-disable-next-line camelcase
  MENU_ENCYPT_TYPE_NUll,
} = mapping;
const _sortBy = memoizeOne(sortBy, isEqual);
const _findIndex = memoizeOne(findIndex, isEqual);
const _find = memoizeOne(find, isEqual);
const _checkMenuPar = memoizeOne(checkMenuPar, isEqual);

const initState = {
  initDataConfirmed: false, // 是否确认过内页的初始化数据
  recent: [], // 最近访问的菜单
  all: [], // 全部菜单(按menuIndex排序过的)
  allByLetter: [],
  collection: [],
  appSysCode: undefined, // app菜单标识
  taskSysCode: undefined,
};

export default {
  namespace: 'menu',

  state: initState,

  effects: {
    *getInitData(_, { call, put, select }) {
      try {
        if (visitor === true) {
          yield put({
            type: 'saveInitData',
            payload: {
              all: allMenu,
              formatAll: [],
              recent: [],
              // appSysCode: response3,
              // taskSysCode: response4,
              allByLetter: [],
              collection: [],
            },
          });
        } else {
          const [response1, response2, response5, response6] = yield [
            call(getAllMenu),
            call(getRecentMenuInfo),
            // call(getSysCodeBySysNbr, { sysNbr: 'APP0' }), // appSysCode
            // call(getSysCodeBySysNbr, { sysNbr: 'RWGL' }), // taskSysCode
            call(selectMenuByLetter), // 按首字母获取当前用户权限菜单列表（叶子菜单）
            call(getCollectionMenu), // 收藏夹菜单
          ];
          if (Array.isArray(response1) && Array.isArray(response2) && Array.isArray(response6)) {
            /**
             * 需要剔除
             * 1、'TYMH_MENU_XTGL_CARD' 对应系统管理-app卡片 二级目录
             * 2、'TYMH_MENU_CARD' 对应app卡片下的三级目录
             */
            yield put({
              type: 'saveInitData',
              payload: {
                all: _sortBy(
                  response1
                    .filter(
                      item => item.menuCode && item.menuCode.indexOf('TYMH_MENU_XTGL_CARD') === -1
                    )
                    .filter(
                      item => item.menuCode && item.menuCode.indexOf('TYMH_MENU_CARD') === -1
                    ),
                  'menuIndex'
                ),
                formatAll: _checkMenuPar(
                  _sortBy(response1, 'menuIndex'),
                  MENU_TYPE_LEAF,
                  MENU_OPEN_MODE_WORK_BENCH_LABEL,
                  MENU_ENCYPT_TYPE_NUll
                ),
                recent: response2,
                // appSysCode: response3,
                // taskSysCode: response4,
                allByLetter: response5,
                collection: response6,
              },
            });

            const userId = yield select(state => state.login.user.userInfo.userId);

            /**
             * 读取用户本地的偏好配置
             * 必须放在这个节点，原因：这个位置在登录状态时每次刷新页面都能被执行到
             * 放在type:'login/login'成功的时候不合适
             */
            yield put({
              type: 'setting/readUserLocalSettings',
              payload: userId,
            });
          }
        }

        yield put({
          type: 'saveInitData',
          payload: { initDataConfirmed: true },
        });
      } catch (e) {
        // 获取初始数据失败
        router.push('/500');

        yield put({
          type: 'saveInitData',
          payload: { initDataConfirmed: true },
        });
      }
    },

    *refreshMenu(_, { call, put }) {
      try {
        const response = yield call(fetchMenu);
        if (response === true) {
          const [response1, response2] = yield [
            call(getAllMenu),
            call(selectMenuByLetter), // 按首字母获取当前用户权限菜单列表（叶子菜单）
          ];
          if (Array.isArray(response1) && Array.isArray(response2)) {
            yield put({
              type: 'saveInitData',
              payload: {
                all: _sortBy(response1, 'menuIndex'),

                allByLetter: response2,
              },
            });
          }
          yield put({
            type: 'saveInitData',
            payload: { initDataConfirmed: true },
          });
        }
      } catch (e) {
        // 获取初始数据失败
        router.push('/500');
        yield put({
          type: 'saveInitData',
          payload: { initDataConfirmed: true },
        });
      }
    },

    // *getRecentMenu(_, { call, put }) {
    //   const response = yield call(getRecentMenuInfo);
    //   try {
    //     if (Array.isArray(response)) {
    //       yield put({
    //         type: 'saveRecent',
    //         payload: response,
    //       });
    //     } else {
    //       message.error('获取历史访问菜单失败');
    //     }
    //     // eslint-disable-next-line no-empty
    //   } catch (e) {}
    // },

    /**
     * 注意：all中的菜单格式需要转换成recent的
     */
    *updateRecentMenu({ payload }, { call, put, select }) {
      // const response = yield call(updateRecentMenu, payload);
      // if (response === 1) {
      const recent = yield select(state => state.menu.recent);
      const all = yield select(state => state.menu.all);
      const index = _findIndex(recent, { recentContent: String(payload) });
      let newRecent = [];
      // 从当前recent中查找，
      // 不存在,则从all中提取菜单数据，放到recent第一位
      // 存在,则从recent中挪到第一位
      if (index === -1) {
        // IMPROVE: all和recent格式统一
        newRecent = [transform(_find(all, { menuId: parseInt(payload, 10) })), ...recent];
      } else {
        const item = recent.splice(index, 1);
        newRecent = [...item, ...recent];
      }
      yield put({
        type: 'saveRecent',
        payload: newRecent,
      });
      // } else if (response === 0) {
      //   message.error('更新历史菜单失败！');
      // }
    },
    /**
     * 注意：all中的菜单格式需要转换成recent的
     */
    // *getCollectionMenu({ payload }, { call, put, select }) {
    //   const response = yield call(getCollectionMenu, payload);
    //   if (response === 1) {
    //     const recent = yield select(state => state.menu.recent);
    //     const formatAll = yield select(state => state.menu.formatAll);
    //     const index = _findIndex(recent, { recentContent: String(payload) });
    //     let newRecent = [];
    //     if (index === -1) {
    //       // IMPROVE: all和recent格式统一
    //       newRecent = [transform(_find(formatAll, { menuId: parseInt(payload, 10) })), ...recent];
    //     } else {
    //       recent.splice(index);
    //       newRecent = [recent[index], recent];
    //     }
    //     yield put({
    //       type: 'saveRecent',
    //       payload: newRecent,
    //     });
    //   } else if (response === 0) {
    //     message.error('更新历史菜单失败！');
    //   }
    // },
    *updateCollectionMenu({ payload }, { call, put }) {
      const { collection, close } = payload;
      const response = yield call(updateCollectionMenu, collection);
      if (response.resultCode === '0') {
        message.success('收藏成功');
        close();
        yield put({
          type: 'saveCollection',
          payload: collection,
        });
      } else {
        message.error(response.resultMsg);
      }
    },
  },

  reducers: {
    saveInitData(state, { payload }) {
      return {
        ...state,
        ...payload,
      };
    },
    saveAll(state, { payload }) {
      return {
        ...state,
        all: payload.response,
      };
    },
    saveRecent(state, { payload }) {
      return {
        ...state,
        recent: payload,
      };
    },
    saveCollection(state, { payload }) {
      return {
        ...state,
        collection: payload,
      };
    },
    reset() {
      return initState;
    },
  },
};
